home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gwu / dclmap.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  8KB  |  295 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. #include "hdr.h"
  11. #include "vars.h"
  12. #include "miscp.h"
  13. #include "dclmapp.h"
  14.  
  15. /* These procedures maintain dstrings, a set of strings and associated
  16.  * hash table used to assign a short integer uniquely identifiying each
  17.  * identifier occurring in a declared map. Each string is preceded by a
  18.  * short integer giving the offset of the next string in the hash chain.
  19.  */
  20.  
  21. /* number of hash blocks, must be power of two (cf. dcl_lookup) */
  22. #define DSTRINGS_HASH    64
  23.  
  24. /* DSTRINGS_MAXLEN gives the maximum length of the dstrings block. The
  25.  * current value reflects the use of a 15 bit value for the idnum in the
  26.  * layout of the Dment block used for a declared map entry.
  27.  */
  28. #define DSTRINGS_MAXLEN        32760
  29.  
  30. static unsigned short dcl_lookup(char *);
  31. static Symbol dcl_getp(Declaredmap, char *, int);
  32.  
  33. char   *dstrings;        /* data block  - used in FORDECLARED */
  34.  
  35. static unsigned short dstrings_expand; /* amount to extend when block full */
  36. static unsigned short dstrings_curlen;/* current length in bytes */
  37. static unsigned short dstrings_maxlen;/* allocated length in bytes */
  38. static unsigned short dhashtable[DSTRINGS_HASH];
  39.  
  40. void dstrings_init(unsigned int init_length, unsigned int expand_count)
  41. /*;dstrings_init*/
  42. {
  43.     int     i;
  44.  
  45.     for (i = 0; i < DSTRINGS_HASH; i++)
  46.         dhashtable[i] = 0;
  47.     dstrings = (char *) emalloct((unsigned) init_length, "dclmap-dstrings");
  48.     dstrings_curlen = sizeof(short);
  49.     dstrings_maxlen = init_length;
  50.     dstrings_expand = expand_count;
  51. }
  52.  
  53. static unsigned short dcl_lookup(char *s)            /*;dcl_lookup*/
  54. {
  55.     /* locate string in dstrings block, adding if not yet present */
  56.  
  57.     unsigned short  hash, i, n;
  58.     unsigned short *dp;
  59.  
  60.     hash = strhash(s) & (DSTRINGS_HASH-1);
  61.     for (i = dhashtable[hash]; i != 0; i = *((unsigned short *)(dstrings + i)))
  62.         if (strcmp(s, (char *)(dstrings + i + sizeof(short))) == 0)
  63.             return i + sizeof(short);
  64.  
  65.     /* here if not found */
  66.     n = strlen(s) + sizeof(short) + 1;/* number of new bytes */
  67. #ifdef ALIGN2
  68.     if (n&1) n+=1; /* round to even to keep shorts aligned */
  69. #ifdef ALIGN4
  70.     if (n&2) n+=2; 
  71. #endif
  72. #endif
  73.     if ((DSTRINGS_MAXLEN - dstrings_maxlen) < dstrings_expand)
  74.         capacity("dstrings full");
  75.  
  76.     if (dstrings_curlen + n >= dstrings_maxlen) {/* if need to extend */
  77.         dstrings_maxlen += dstrings_expand;
  78.         dstrings = (char *) erealloct(dstrings, dstrings_maxlen,
  79.             "dstrings-realloc");
  80.     }
  81.     dp = (unsigned short *)(dstrings + dstrings_curlen);
  82.     *dp = dhashtable[hash];
  83.     dhashtable[hash] = dstrings_curlen;
  84.     strcpy(dstrings + dstrings_curlen + sizeof(short), s);
  85.     dstrings_curlen += n;
  86.     return dhashtable[hash] + sizeof(short);
  87. }
  88.  
  89. Declaredmap dcl_new(int nh)    /*;dcl_new*/
  90. {
  91.     /* Allocate declared map with nh hash headers(0->10 headers */
  92.  
  93.     Declaredmap dm;
  94.  
  95.     dm = (Declaredmap) ecalloct(1, sizeof(Declaredmap_s), "dcl-new-dm");
  96.  
  97.     nh = nh == 0 ? 4 : nh;
  98.     dm->dmap_curlen = 0;
  99.     dm->dmap_maxlen = nh;
  100.     dm->dmap_table = (struct Dment   *) ecalloct((unsigned) nh,
  101.       sizeof(Dment), "dcl-new-dmap-table");
  102.  
  103.     return dm;
  104. }
  105.  
  106.  
  107. Symbol dcl_get_vis(Declaredmap dmap, char *s)    /*;dcl_get_vis*/
  108. {
  109.     /* return Symbol for string s if present in map else appropriate
  110.      * This is to return only if visible.
  111.      */
  112.     return dcl_getp(dmap, s, TRUE);
  113. }
  114.  
  115. Symbol dcl_get(Declaredmap dmap, char *s)        /*;dcl_get*/
  116. {
  117.     return dcl_getp(dmap, s, FALSE);
  118. }
  119.  
  120. static Symbol dcl_getp(Declaredmap dmap, char *s, int ifvis) /*;dcl_getp*/
  121. {
  122.     /* return Symbol for string s if present in map else appropriate
  123.      * null pointer . If ifvis is TRUE then return only if entry visible.
  124.      */
  125.  
  126.     unsigned short  idnum, i;
  127.     struct Dment   *p;
  128.  
  129.     if (dmap == (Declaredmap) 0)
  130.         chaos("dcl_getp: declared map null pointer");
  131.     idnum = dcl_lookup(s);
  132.     p = dmap->dmap_table;
  133.     for (i = 0; i < dmap->dmap_curlen; i++, p++) {
  134.         if (p->dment_i.dment_idnum == idnum) {/* if match */
  135.             /* fail if must be visible and symbol not visible */
  136.             if (ifvis && p->dment_i.dment_visible == 0)
  137.                 return (Symbol) 0;
  138.             else    /* here if want returned ignoring visibility */
  139.                 return (p->dment_symbol);
  140.         }
  141.     }
  142.     /* here if not present */
  143.     return (Symbol) 0;
  144. }
  145.  
  146. void dcl_put_vis(Declaredmap dmap, char *s, Symbol sym, int vis)
  147. /*;dcl_put_vis*/
  148. {
  149.     /* Set symbol for s to be sym, adding s to map if necessary */
  150.  
  151.     unsigned short  idnum;
  152.     struct Dment   *p;
  153.     int     i;
  154.  
  155.     if (dmap == (Declaredmap) 0)
  156.         chaos("dcl_put: declared map NULL");
  157.     idnum = dcl_lookup(s);
  158.     p = dmap->dmap_table;
  159. #ifdef DEBUG
  160.     /* Ultimately this code should be removed. Since this check should
  161.      * never yield a duplicate value under the new scheme where entries
  162.      * that already exist are removed first before being reentered.
  163.      */
  164.     for (i = 0; i < dmap->dmap_curlen;(i++, p++)) {
  165.         if (idnum == p->dment_i.dment_idnum) {/* if match */
  166.             chaos(strjoin("dcl_put_vis found duplicate entry", s));
  167.             p->dment_i.dment_visible = vis;
  168.             p->dment_symbol = sym;
  169.             return;
  170.         }
  171.     }
  172. #endif
  173.  
  174.     /* here if not present, add to table */
  175.     if (dmap->dmap_curlen >= dmap->dmap_maxlen) {/* need to expand */
  176.         dmap->dmap_maxlen += 4;        /* allocate room for four more entries */
  177.         /* dmap_chk(dmap, "realloc"); */
  178.         dmap->dmap_table = (struct Dment *) erealloct((char *) dmap->dmap_table,
  179.           (unsigned) (dmap->dmap_maxlen * sizeof(Dment)), "dcl-put-realloc");
  180.     }
  181.     p = dmap->dmap_table + dmap->dmap_curlen;
  182.     p->dment_i.dment_idnum = idnum;
  183.     p->dment_i.dment_visible = vis;
  184.     dmap->dmap_curlen += 1;
  185.     /* dmap_chk(dmap, "retrieve"); */
  186.     p->dment_symbol = sym;
  187.     return;
  188. }
  189.  
  190. void dcl_put(Declaredmap dmap, char *s, Symbol sym)    /*;dcl_put*/
  191. {
  192.     dcl_put_vis(dmap, s, sym, FALSE);
  193. }
  194.  
  195. void dcl_undef(Declaredmap dmap, char *s)        /*;dcl_undef*/
  196. {
  197.     /* Set entry for s to be undefined if presently defined */
  198.  
  199.     unsigned short  idnum, i, j;
  200.     struct Dment   *p;
  201.  
  202.     idnum = dcl_lookup(s);
  203.     p = dmap->dmap_table;
  204.     for (i = 0; i < dmap->dmap_curlen;(i++, p++)) {
  205.         if (idnum == p->dment_i.dment_idnum) {/* if found */
  206. #ifdef IBM_PC
  207.             /* need memcpy for PC, as possible code generation bug causes
  208.              * problem on PC if use array code        ds 4-26-86
  209.              */
  210.             dmap->dmap_curlen -= 1;
  211.             if (i <dmap->dmap_curlen)
  212.                 memcpy((char *)p, (char *) (p+1) ,
  213.                   ((dmap->dmap_curlen - i) * sizeof(Dment)));
  214. #else
  215.             for (j = i + 1; j < dmap->dmap_curlen; j++)
  216.                 dmap->dmap_table[j - 1] = dmap->dmap_table[j];
  217.             dmap->dmap_curlen -= 1;
  218. #endif
  219.             return;
  220.         }
  221.     }
  222. }
  223.  
  224. Declaredmap dcl_copy(Declaredmap dm)    /*;dcl_copy*/
  225. {
  226.     /* return copy of declared map */
  227.  
  228.     Fordeclared fd;
  229.     Symbol sa;
  230.     char   *id;
  231.     Declaredmap rm;
  232.  
  233.     if (dm == (Declaredmap) 0) chaos("dcl_copy: declared map NULL");
  234.  
  235.     rm = dcl_new(dm->dmap_curlen);
  236.     FORDECLARED(id, sa, dm, fd)
  237.         dcl_put_vis(rm, id, sa, IS_VISIBLE(fd));
  238.     ENDFORDECLARED(fd)
  239.     return (rm);
  240. }
  241.  
  242. #ifdef DEBUG_DCL
  243. dstrings_dump()            /*;dstrings_dump*/
  244. {
  245.     int i, n=0;
  246.     unsigned short j;
  247.  
  248.     printf("dstrings dump\n");
  249.     for (i=0; i<DSTRINGS_HASH; i++) {
  250.         for (j=dhashtable[i]; j != 0; 
  251.             j = *((unsigned short *)(dstrings + j)) ) {
  252.             printf("%5d %5d %s\n", i, j,  dstrings + j +sizeof(short));
  253.             n++;
  254.         }
  255.     }
  256.     printf("%d entries require %u\n", n, dstrings_curlen);
  257. }
  258.  
  259. dmap_chk(Declaredmap dmap, char *lab)                /*;dmap_chk*/
  260. {
  261.     struct Dment * p;
  262.     int    i;
  263.  
  264.     return;
  265.     printf("dmap chk %s\n", lab);
  266.     p = dmap->dmap_table;
  267.     for (i=0; i<dmap->dmap_curlen; i++, p++) {
  268.         if (p->dment_symbol == (Symbol)0) {
  269.             printf("dmap_chk fails %s\n", lab);
  270.             chaos("dmap_chk");
  271.         }
  272.     }
  273. }
  274.  
  275. int dcl_dump(Declaredmapdm)        /*;dcl_dump*/
  276. {
  277.     /* write dm to standard output */
  278.  
  279.     int     i, n=0;
  280.     struct Dment   *p;
  281.  
  282.     printf("dm dump\n");
  283.  
  284.     p = dm->dmap_table;
  285.     for (i = 0; i < dm->dmap_curlen;(i++, p++)) {
  286.         n++;
  287.         printf("%u %u %s %lu\n", p->dment_i.dment_visible, 
  288.           p->dment_i.dment_idnum,
  289.           dstrings + p->dment_i.dment_idnum, p->dment_symbol);
  290.     }
  291.     printf("%d entries in map, dstrings: curlen %u  maxlen %u\n", n,
  292.         dstrings_curlen, dstrings_maxlen);
  293. }
  294. #endif
  295.